﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

using AKMII.DMRA.Common;
using AKMII.DMRA.DataAccess;
using AKMII.DMRA.Business.Rule;

namespace AKMII.DMRA.Business.Management
{
    public class OrderManager
    {
        private OrderAccessor orderAccessor;
        private ZipAccessor zipAccessor;

        public OrderManager()
        {
            orderAccessor = new OrderAccessor();
            zipAccessor = new ZipAccessor();
        }

        public bool InsertOrderRepeatRemark(string mdnumber, int month, int year, int zipId, string reason)
        {
            bool result = false;

            try
            {
                result = orderAccessor.AddOrderRepeatRemark(mdnumber, month, year, zipId, reason);
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in add order repeat remark", ex);
            }

            return result;
        }

        public bool ManageOrder(Order order)
        {
            bool result = false;

            try
            {
                result = orderAccessor.AddOrder(order.Id,
                    order.AccountId, order.PeroidYear, order.PeroidMonth, ConstructZipIdString(order.Zips));
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in manage order", ex);
            }

            return result;
        }

        public bool ManageOrder(Order order, string agentName, int week)
        {
            bool result1 = false;
            bool result2 = false;

            try
            {
                string assignment =  week.ToString() + " " + agentName;
                result1 = orderAccessor.AddOrderNew(order.Id,
                    order.AccountId, order.PeroidYear, order.PeroidMonth, ConstructZipIdString(order.Zips.Where(c => string.IsNullOrEmpty(c.UserAssigned) || c.UserAssigned == assignment).ToList<LeadBlock>()), assignment);

                result2 = zipAccessor.UpdateZipAssigned(assignment,
                        ConstructMapZipIdString(order.Zips.Where(c => string.IsNullOrEmpty(c.UserAssigned) || c.UserAssigned == assignment).ToList<LeadBlock>()),
                        order.PeroidMonth, order.PeroidYear,
                        (order.PeroidMonth == CurrentPeriod.Month && order.PeroidYear == CurrentPeriod.Year));
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in manage order by agent and week", ex);
            }

            return result1 && result2;
        }

        public bool ManageOrder(Order order, int operationType)
        {
            bool result = false;

            try
            {
                if (operationType == 0)
                {
                    result = orderAccessor.AddMapOrder(order.Id,
                        order.AccountId, order.PeroidYear, order.PeroidMonth, ConstructMapZipIdString(order.Zips));
                }
                else if (operationType == 1)
                {
                    result = orderAccessor.DeleteMapOrder(order.Id,
                        order.AccountId, order.PeroidYear, order.PeroidMonth, ConstructMapZipIdString(order.Zips));
                }
                else
                {
                    //Noting to do
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in manage map order", ex);
            }

            return result;
        }

        public bool ManageOrder(Order order, int operationType, string agentName, int week)
        {
            bool result1 = false;
            bool result2 = false;

            try
            {
                if (operationType == 0)
                {
                    result1 = orderAccessor.AddMapOrder(order.Id,
                        order.AccountId, order.PeroidYear, order.PeroidMonth, ConstructMapZipIdString(order.Zips));

                    result2 = zipAccessor.UpdateZipAssigned(week.ToString() + " " + agentName,
                        ConstructMapZipIdString(order.Zips.Where(c => string.IsNullOrEmpty(c.UserAssigned)).ToList<LeadBlock>()),
                        order.PeroidMonth, order.PeroidYear,
                        (order.PeroidMonth == CurrentPeriod.Month && order.PeroidYear == CurrentPeriod.Year));
                }
                else if (operationType == 1)
                {
                    result1 = orderAccessor.DeleteMapOrder(order.Id,
                        order.AccountId, order.PeroidYear, order.PeroidMonth, ConstructMapZipIdString(order.Zips));

                    result2 = zipAccessor.UpdateZipAssigned(null, ConstructMapZipIdString(order.Zips),
                        order.PeroidMonth, order.PeroidYear, (order.PeroidMonth == CurrentPeriod.Month && order.PeroidYear == CurrentPeriod.Year));
                }
                else
                {
                    //Noting to do
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in manage map order", ex);
            }

            return result1 && result2;
        }

        public bool ManageOrder(Order order, int operationType, string zipName)
        {
            bool result = false;

            try
            {
                order.Zips = zipAccessor.GetLeadBlock(zipName);

                if (operationType == 0)
                {
                    result = orderAccessor.AddMapOrder(order.Id,
                        order.AccountId, order.PeroidYear, order.PeroidMonth, ConstructMapZipIdString(order.Zips));
                }
                else if (operationType == 1)
                {
                    result = orderAccessor.DeleteMapOrder(order.Id,
                        order.AccountId, order.PeroidYear, order.PeroidMonth, ConstructMapZipIdString(order.Zips));
                }
                else
                {
                    //Noting to do
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in manage map order for zip code", ex);
            }

            return result;
        }

        public List<LeadBlock> GetOrderHistory(string AccountID, int Year, int Month)
        {
            List<LeadBlock> zips = null;
             try
            {
               zips=orderAccessor.GetOrderHistory(AccountID, Year, Month);
            }
             catch (Exception ex)
            {
                Logger.Error("Exception occous in GetOrderHistory", ex);
            }

            return zips;
        }

        public bool PurchaseOrder(int orderId)
        {
            bool result = false;
            try
            {
                result = orderAccessor.UpdateOrderStatus(orderId);
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in purchase order", ex);
            }
            return result;
        }

        public bool PurchaseOrder(int orderId, int PurchasedStatus)
        {
            bool result = false;
            try
            {
                result = orderAccessor.UpdateOrderStatus(orderId,PurchasedStatus);
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in purchase order", ex);
            }
            return result;
        }

        public Order GetOrder(string userId, int month, int year)
        {
            Order order = null;

            try
            {
                order = orderAccessor.GetOrderByIdAndDate(userId, month, year);
                if (order != null)
                {
                    order.Zips = zipAccessor.GetLeadBlock(userId, month, year, 1);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Exception occurs in get order", ex);
            }

            return order;
        }

        private string ConstructMapZipIdString(List<LeadBlock> zips)
        {
            StringBuilder allZipIds = new StringBuilder(string.Empty);

            if (zips != null && zips.Count > 0)
            {
                for (int i = 0; i < zips.Count; i++)
                {
                    allZipIds.Append(zips[i].ZipId.ToString());

                    if (i != (zips.Count - 1))
                    {
                        allZipIds.Append(',');
                    }
                }
            }

            return allZipIds.ToString();
        }

        private string ConstructZipIdString(List<LeadBlock> zips)
        {
            StringBuilder allZipIds = new StringBuilder(string.Empty);

            if (zips != null && zips.Count > 0)
            {
                for (int i = 0; i < zips.Count; i++)
                {
                    allZipIds.Append(zips[i].ZipId.ToString() + ";" + Convert.ToInt32(zips[i].Type).ToString());

                    if (i != (zips.Count - 1))
                    {
                        allZipIds.Append(',');
                    }
                }
            }

            return allZipIds.ToString();
        }
    }
}
